/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       mage_guild_window.h

	$Header: /game/mage_guild_window.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "mage_guild_window.h"

#include "adaptor_handler.h"
#include "army.h"
#include "bitmap_group_cache.h"
#include "blended_bitmap_window.h"
#include "bound_handler.h"
#include "button.h"
#include "button_cache.h"
#include "creature_traits.h"
#include "creature_type.h"
#include "debug_message.h"
#include "elements_of.h"
#include "external_string.h"
#include "format_string.h"
#include "game_replace_keywords.h"
#include "hero.h"
#include "interface_help.h"
#include "item_help_block.h"
#include "spell.h"
#include "spell_icon.h"
#include "spell_icon_window.h"
#include "spell_properties.h"
#include "standard_fonts.h"
#include "string_insensitive_compare.h"
#include "text_window.h"
#include "town.h"
#include "town_properties.h"

namespace
{
	class t_sort_spells
	{
	public:
		bool operator()( t_spell left, t_spell right ) const
		{
			return string_insensitive_compare( get_spell_name( left ), get_spell_name(right) ) 
				   < 0;
		}
	};

}; // unnamed namespace

extern t_bitmap_group_cache const k_frame_bitmaps;

static t_bitmap_group_cache k_book_bitmaps( "dialog.mage_guild.book" );
t_bitmap_group_cache const k_frame_bitmaps( "icons.spellbook_frames" );
static t_bitmap_group_cache k_background_bitmaps[] =
{
	"dialog.mage_guild.life_1024",
	"dialog.mage_guild.life_1280",
	"dialog.mage_guild.order_1024",
	"dialog.mage_guild.order_1280",
	"dialog.mage_guild.death_1024",
	"dialog.mage_guild.death_1280",
	"dialog.mage_guild.chaos_1024",
	"dialog.mage_guild.chaos_1280",
	"dialog.mage_guild.nature_1024",
	"dialog.mage_guild.nature_1280",
};

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
t_mage_guild_window::t_mage_guild_window( t_town const* town, t_army const* adjacent_army,
										  t_window* parent )
                   : t_window( k_completely_transparent, parent )
{
	t_screen_rect rect;
	t_screen_rect parent_rect;

	m_current_page = 0;

	// load bitmaps
	m_town = town;
	m_adjacent_army = adjacent_army;
	m_book_bitmaps = k_book_bitmaps.get();
	m_frame_bitmaps = k_frame_bitmaps.get();


	t_bitmap_layer const *	layer;
	t_window *				window;
	t_screen_point			origin(0,0);
	t_screen_point			book_origin(0,0);

	parent_rect = get_parent()->get_client_rect();
	if( parent_rect.width() >= 1024 )
	{
		int ndx = town->get_type() * 2;
		if( parent_rect.width() > 1024 )
			++ndx;

		assert( ndx < ELEMENTS_OF(k_background_bitmaps) );

		m_background_bitmaps = k_background_bitmaps[ndx].get();

		rect = m_background_bitmaps->get_rect();
		rect += (parent_rect.size() - rect.size()) / 2;

		// create background
		layer = m_background_bitmaps->find( "top" );
		window = new t_bitmap_layer_window( layer, origin, this );
		layer = m_background_bitmaps->find( "left" );
		window = new t_bitmap_layer_window( layer, origin, this );
		layer = m_background_bitmaps->find( "bottom" );
		window = new t_bitmap_layer_window( layer, origin, this );
		layer = m_background_bitmaps->find( "right" );
		window = new t_bitmap_layer_window( layer, origin, this );

		book_origin = m_background_bitmaps->find( "book_pages" )->get_rect().top_left();
	} else
		rect = parent_rect;

	init( rect );

	// create book
	t_window*      book;

	layer = m_book_bitmaps->find( "book_pages" );
	book = new t_bitmap_layer_window( layer, book_origin, this );
	rect = book->get_client_rect();
	m_index_window = new t_window( rect, k_completely_transparent, book );
	m_detail_window = new t_window( rect, k_completely_transparent, book );
	m_detail_window->set_visible( false );

	// create and sort spell list
	int                       i;
	t_guild_spell_list const& spells = m_town->get_spells();

	for (i = 0; i < spells.size(); i++)
	{
		if (spells[i].available)
			m_spells.push_back( spells[i].spell );
	}
	std::sort( m_spells.begin(), m_spells.end(), t_sort_spells());

	create_buttons( book_origin );
	create_spell_icons();
	create_labels();
	create_detail_page();
	create_hero_icons();

	// set up initial spell set visibility
	m_current_page = 1;
	change_spell_set_visibility( false );
	m_current_page = 0;
	change_spell_set_visibility( true );

	// set whether page buttons are visible or not
	if( m_icon_list[1].size() == 0 )
	{
		m_last_page_button->set_visible(false);
		m_next_page_button->set_visible(false);
	}
}

// -------------------c-----------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::close_click( t_button* )
{
	close();
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
static t_button_cache k_close_button( "button.mage_guild.close" );
static t_button_cache k_last_spell_button( "button.mage_guild.last_spell" );
static t_button_cache k_next_spell_button( "button.mage_guild.next_spell" );
static t_button_cache k_last_hero_button( "button.spellbook.last_hero" );
static t_button_cache k_next_hero_button( "button.spellbook.next_hero" );
t_button_cache		  k_spellbook_index_button( "button.spellbook.index" );

void t_mage_guild_window::create_buttons( t_screen_point book_origin )
{
	t_button*     button;
	t_screen_rect rect;
	t_help_block const & detail_help = get_help_block( "mage_guild" );
	t_help_block const&	shared_help = get_help_block( "shared" );

	// create close button
	rect = m_book_bitmaps->find( "close_button" )->get_rect();
	button = new t_button( k_close_button.get(), rect.top_left() + book_origin, this );
	button->set_click_handler( bound_handler( *this, &t_mage_guild_window::close_click ));
	set_help( button, shared_help, "cancel" );

	// next and last spell buttons
	rect = m_book_bitmaps->find( "last_spell_button" )->get_rect();
	m_last_spell_button = new t_button( k_last_spell_button.get(), rect.top_left(), 
		                                m_detail_window );
	m_last_spell_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::last_spell_click ));
	rect = m_book_bitmaps->find( "next_spell_button" )->get_rect();
	m_next_spell_button = new t_button( k_next_spell_button.get(), rect.top_left(), 
		                                m_detail_window );
	m_next_spell_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::next_spell_click ));

	// next and last page buttons
	rect = m_book_bitmaps->find( "previous_page" )->get_rect();
	m_last_page_button = new t_button( k_last_spell_button.get(), rect.top_left(), 
		                                m_index_window );
	m_last_page_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::last_page_click ));
	m_last_page_button->set_visible( false );

	rect = m_book_bitmaps->find( "next_page" )->get_rect();
	m_next_page_button = new t_button( k_next_spell_button.get(), rect.top_left(), 
		                                m_index_window );
	m_next_page_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::next_page_click ));
	m_next_page_button->set_visible( true );

	// next and last hero buttons
	rect = m_book_bitmaps->find( "last_hero_button" )->get_rect();
	m_last_hero_button = new t_button( k_last_hero_button.get(), rect.top_left(), 
		                                m_detail_window );
	rect = m_book_bitmaps->find( "next_hero_button" )->get_rect();
	m_next_hero_button = new t_button( k_next_hero_button.get(), rect.top_left(), 
		                                m_detail_window );
	m_last_hero_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::last_hero_click ));
	m_next_hero_button->set_click_handler( bound_handler( *this, 
											&t_mage_guild_window::next_hero_click ));
	// close detail button
	rect = m_book_bitmaps->find( "index_button" )->get_rect();
	button = new t_button( k_spellbook_index_button.get(), rect.top_left(), m_detail_window );
	button->set_click_handler( bound_handler( *this, &t_mage_guild_window::index_click ));
	set_help( button, detail_help, "back_to_index" );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::create_detail_page()
{
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
t_external_string k_text_hero_list( "hero_list.mage_guild" );
static t_external_string const k_text_level_x_spell( "level_x_spells.mage_guild" );
t_font_cache k_script_font( "script.18" );

void t_mage_guild_window::create_labels()
{
	t_bitmap_layer const *	layer;
	t_window *				window;
	t_screen_point			origin(0,0);
	t_text_window*	text_window;
	t_screen_rect	rect;
	int				i;
	std::string     text;
	int ndx = 1;

	for ( i = 1; i <= 5; i++)
	{
		// spell level background
		ndx = i;
		if(	ndx == 3 )
			ndx = 1;
		else
		if( ndx == 4 )
			ndx = 2;
		layer = m_book_bitmaps->find( format_string( "level_%i_spells_background", ndx ) );
		rect = layer->get_rect();
		window = new t_bitmap_layer_window( layer, origin, m_index_window );
		window->set_visible(false);
		int page = 0;
		if( i > 2 )
			page = 1;
		m_level_banner_list[page].push_back(window);

		// label
		rect = m_book_bitmaps->find( format_string( "level_%i_spells", i ) )->get_rect();
		text = replace_keywords( k_text_level_x_spell, "%level", format_string( "%i", i ));
		text_window = new t_text_window( get_font( rect.height() ), rect, m_index_window,
			                             text, t_pixel_24(0,0,0));
		text_window->set_center_horizontal();
		text_window->set_center_vertical();
		text_window->set_drop_shadow( true, t_pixel_24( 200,200,200 ));
		text_window->set_visible(false);
		m_label_list[page].push_back(text_window);
	}

	rect = m_book_bitmaps->find( "spell_name" )->get_rect();
	m_spell_name = new t_text_window( get_font( rect.height() ), rect, m_detail_window, "",
		                              t_pixel_24(0,0,0) );
	m_spell_name->set_center_horizontal();
	m_spell_name->set_center_vertical();
	m_spell_name->set_drop_shadow( true, t_pixel_24(200,200,200));

	rect = m_book_bitmaps->find( "description_text" )->get_rect();
	m_spell_text = new t_text_window( get_font( 20 ), rect, m_detail_window, "", 
		                              t_pixel_24(0,0,0));
	m_spell_text->set_drop_shadow( true, t_pixel_24(200,200,200));
	m_maximum_description_height = rect.height();

	m_spell_comment = new t_text_window( k_script_font.get(), rect, m_detail_window, "",
		                                 t_pixel_24(0,0,0));
	m_spell_comment->set_drop_shadow( true, t_pixel_24(200,200,200));

	rect = m_book_bitmaps->find( "hero_list" )->get_rect();
	text_window = new t_text_window( get_font( rect.height() ), rect, m_detail_window, k_text_hero_list,
		                              t_pixel_24(0,0,0) );
	text_window->set_center_horizontal();
	text_window->set_center_vertical();
	text_window->set_drop_shadow( true, t_pixel_24(200,200,200));


}

/*
void t_mage_guild_window::add_spells( t_spell_tester const& valid_spell )
{
	t_spell spell;

	m_spells.clear();
	for (spell = t_spell(0); spell < k_spell_count; enum_incr(spell))
	{
		if (m_creature->knows_spell( spell ) && valid_spell( spell ))
			m_spells.push_back( spell );
	}
	add_artifacts( valid_spell );
}
*/

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::create_hero_icons()
{
	t_bitmap_layer const* frame;
	t_screen_point        frame_origin;
	t_screen_rect         rect;
	t_screen_point        icon_origin;
	t_screen_rect         text_rect;
	int                   i;

	frame = m_frame_bitmaps->find( "hero_frame" );
	frame_origin = frame->get_rect().top_left();
	rect = m_frame_bitmaps->find( "hero_portrait" )->get_rect();
	icon_origin = rect.top_left() - frame_origin;
	text_rect = m_frame_bitmaps->find( "hero_text" )->get_rect() - frame_origin;
	for (i = 0; i < k_hero_icon_count; i++)
	{
		rect = m_book_bitmaps->find( format_string( "hero_frame_%i", i + 1 ))->get_rect();
		m_hero_frames[i].icon = new t_bitmap_layer_cache_window( t_bitmap_layer_ptr(),
			                                                     icon_origin + rect.top_left(), 
																 m_detail_window, false );
		m_hero_frames[i].frame = new t_bitmap_layer_window( frame, rect.top_left(), 
			                                                m_detail_window, false );
		m_hero_frames[i].text = new t_text_window( get_font(16), text_rect + rect.top_left(),
			                                       m_detail_window, "", t_pixel_24(0,0,0));
		m_hero_frames[i].text->set_drop_shadow( true, t_pixel_24(200,200,200));
	}
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::create_spell_icons()
{
	static int const          k_layout[5][3][3] = 
	{
		{ { 1, 2, 3 },	{ 4, 5 },	{ 6, 7 } },
		{ { 1, 2, 3 },	{ 4, 5 },	{ 6, 7 } },
		{ { 1, 2 },		{ 3, 4 },	{ 5, 6 } },
		{ { 1, 2 },		{ 3 },		{ 4 } },
		{ { 1 },		{ 2 },		{ 3 } },
	};

	int                       level;
	t_guild_spell_list const& spells = m_town->get_spells();
	int                       i;
	int                       spell_count[5][3];
	std::string               layer_name;
	t_screen_rect             rect;
	t_screen_rect             text_frame_rect;
	t_screen_rect             text_rect;
	t_bitmap_layer const *    frame;
	t_bitmap_layer const *    layer;
	t_screen_rect             icon_rect;
	t_window*                 window;
	t_button*                 button;
	t_text_window*            text_window;
	t_town_type               alignment;
	t_spell                   spell;
	int                       frame_number;
	int                       library;
	int                       count;

	memset( spell_count, 0, sizeof(spell_count));
	rect = m_book_bitmaps->find( "level_1_frame_1" )->get_rect();
	text_frame_rect = m_book_bitmaps->find( "spell_background" )->get_rect() - rect.top_left();
	text_rect = m_book_bitmaps->find( "level_1_name_1" )->get_rect() - rect.top_left();
	icon_rect = m_frame_bitmaps->find( "spell_icon" )->get_rect();
	for (i = 0; i < m_spells.size(); i++)
	{
		// spell icon
		spell = m_spells[i];
		level = get_spell_level( spell );
		alignment = get_spell_alignment( spell );
		if (alignment == m_town->get_type())
			library = 0;
		else if (alignment == m_town->get_library_type( k_town_library_1 ))
			library = 1;
		else
			library = 2;
		count = spell_count[level-1][library]++;
		frame_number = k_layout[level-1][library][count];
		layer_name = format_string( "level_%i_frame_%i", level, frame_number );
		layer = m_book_bitmaps->find( layer_name );
		if (layer)
			rect = layer->get_rect();
		else
		{
			DEBUG_MESSAGE( format_string( "Missing asset in dialog.mage_guild.book:  %s", layer_name.c_str() ).c_str() );
			assert( !"Missing Asset" );
			continue;
		}

		// frame
		frame = m_frame_bitmaps->find( k_town_keyword[alignment] );
		window = new t_bitmap_layer_window( frame, rect.top_left(), m_index_window, false );
		window->set_visible(false);
		int page = 0;
		if( level > 2 )
			page = 1;
		m_frames_list[page].push_back(window);

		// icon
		button = new t_button( icon_rect.top_left() + rect.top_left(), m_index_window );
		window = new t_spell_icon_window( spell, icon_rect - icon_rect.top_left(), button );
		button->set_released_image( window );
		button->set_click_handler( add_2nd_argument( bound_handler( *this,
			                       &t_mage_guild_window::spell_click ), spell ));
		button->set_visible(false);
		m_icon_list[page].push_back(button);

		// spell desc background
		layer = m_book_bitmaps->find( "spell_background" );
		t_screen_rect desc_rect =  text_frame_rect + rect.top_left();
		window = new t_bitmap_layer_window( layer, desc_rect.top_left(), m_index_window, false );
		window->set_visible(false);
		m_label_banner_list[page].push_back(window);

		// spell name
		text_window = new t_text_window( get_font( 14 ), 
			                             text_rect + rect.top_left() + t_screen_point(0,0),
										 m_index_window, get_spell_name( spell ),
										 t_pixel_24(0,0,0));
		text_window->set_center_horizontal();
		text_window->set_center_vertical();
		text_window->set_drop_shadow( true, t_pixel_24(200,200,200));
		text_window->set_visible(false);
		m_spellname_list[page].push_back(text_window);
	}

	// Details page stuff
	layer = m_book_bitmaps->find( "spell_name_background" );
	rect = layer->get_rect();
	m_spell_name_banner = new t_bitmap_layer_window( layer, rect.top_left(), m_detail_window, false );
	m_spell_name_banner->set_visible(false);

	layer = m_book_bitmaps->find( "hero_list_background" );
	rect = layer->get_rect();
	window = new t_bitmap_layer_window( layer, rect.top_left(), m_detail_window, false );
//	window->set_visible(false);

	rect = m_book_bitmaps->find( "spell_frame" )->get_rect();
	m_spell_frame = new t_bitmap_layer_window( 0, rect.top_left(), m_detail_window );
	m_spell_icon = new t_spell_icon_window( k_spell_none, icon_rect + rect.top_left(),
		                                    m_detail_window );

	rect = m_book_bitmaps->find( "icon_silhouette" )->get_rect();
	m_large_spell_icon_window = new t_blended_bitmap_window( 0, rect.top_left(), m_detail_window,
		                                                     true, 4 );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::index_click( t_button* )
{
	m_detail_window->set_visible( false );
	m_index_window->set_visible( true );
}

static t_spell get_last_spell( t_spell spell, std::vector<t_spell> const& spells )
{
	std::vector<t_spell>::const_iterator index;

	index = std::lower_bound( spells.begin(), spells.end(), spell, t_sort_spells() );
	if (index == spells.begin())
		return k_spell_none;
	index--;
	return *index;
}

static t_spell get_next_spell( t_spell spell, std::vector<t_spell> const& spells )
{
	std::vector<t_spell>::const_iterator index;

	index = std::lower_bound( spells.begin(), spells.end(), spell, t_sort_spells() );
	if (index == spells.end())
		return k_spell_none;
	index++;
	if (index == spells.end())
		return k_spell_none;
	return *index;
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::last_hero_click( t_button* )
{
	if (m_first_hero > 0)
		scroll_hero_list( m_first_hero - 1 );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::last_page_click( t_button * button)
{
	change_spell_set_visibility( false );

	if( (--m_current_page) < 0 )
		m_current_page = 0;

	if( m_current_page == 0 )
	{
		m_last_page_button->set_visible( false );
		m_next_page_button->set_visible( true );
	} else
	{
		m_last_page_button->set_visible( true );
		m_next_page_button->set_visible( false );
	}

	change_spell_set_visibility( true );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::last_spell_click( t_button * button)
{
	t_spell spell = get_last_spell( m_current_spell, m_spells );
	
	if (spell != k_spell_none)
		spell_click( button, spell );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::next_hero_click( t_button* )
{
	if (m_first_hero + k_hero_icon_count < m_heroes.size())
		scroll_hero_list( m_first_hero + 1 );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::next_page_click( t_button * button)
{
	change_spell_set_visibility( false );

	if( (++m_current_page) > 1 )
		m_current_page = 1;

	if( m_current_page == 0 )
	{
		m_last_page_button->set_visible( false );
		m_next_page_button->set_visible( true );
	} else
	{
		m_last_page_button->set_visible( true );
		m_next_page_button->set_visible( false );
	}

	change_spell_set_visibility( true );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::next_spell_click( t_button * button)
{
	t_spell spell = get_next_spell( m_current_spell, m_spells );
	
	if (spell != k_spell_none)
		spell_click( button, spell );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
t_external_string k_text_cost( "Cost.mage_guild" );

void t_mage_guild_window::spell_click( t_button*, t_spell spell )
{
	std::string text = get_spell_help( spell );

	text += "\n\n" + k_text_cost.get() + ": " + format_string( "%i", get_spell_cost( spell ));
	m_index_window->set_visible( false );
	m_detail_window->set_visible( true );
	m_spell_name->set_text( get_spell_name( spell ));
	m_spell_text->set_text( text );

	// compute size of description text.
	t_screen_rect rect   = m_spell_text->get_screen_rect();
	int           height = m_spell_text->get_text_height();

	if (height > m_maximum_description_height)
		height = m_maximum_description_height;
	rect.bottom = rect.top + height;
	m_spell_text->move_screen_rect( rect );

	// find size of flavor text
	t_screen_rect flavor_rect = rect;

	flavor_rect.top = rect.bottom + 20;
	flavor_rect.bottom = rect.top + m_maximum_description_height;
	if (flavor_rect.bottom < flavor_rect.top)
	{
		m_spell_comment->set_visible( false );
	}
	else
	{
		m_spell_comment->set_visible( true );
		m_spell_comment->move_screen_rect( flavor_rect );
		m_spell_comment->set_text( get_spell_flavor_text( spell ));
	}

	// set spell icon
	t_bitmap_layer const* frame;
	t_town_type           alignment;

	m_spell_icon->set_spell( spell );
	alignment = get_spell_alignment( spell );
	frame = m_frame_bitmaps->find( k_town_keyword[alignment] );
	m_spell_frame->set_bitmap( frame );
	m_current_spell = spell;

	// set large spell window
	m_large_spell_icon = get_spell_icon( spell, 180 );
	m_large_spell_icon_window->set_bitmap( m_large_spell_icon );

	m_spell_name_banner->set_visible( true );
	m_last_spell_button->set_visible( get_last_spell( spell, m_spells ) != k_spell_none );
	m_next_spell_button->set_visible( get_next_spell( spell, m_spells ) != k_spell_none );

	m_heroes.clear();
	set_hero_list( m_town->get_garrison() );
	if (m_adjacent_army != 0)
		set_hero_list( m_adjacent_army->get_creatures() );
	scroll_hero_list( 0 );
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// set hero display
// -------------------------------------------------------------------
void t_mage_guild_window::set_hero_list( t_creature_array const& creatures )
{
	int           i;
	t_hero const* hero;

	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero = creatures[i].get_hero();
		if (hero == 0)
			continue;
		if (hero->knows_spell( m_current_spell ))
			m_heroes.push_back( hero );
	}
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// set hero display
// -------------------------------------------------------------------
static t_external_string k_no_heroes_know( "no_knowledge.mage_guild" );


void t_mage_guild_window::scroll_hero_list( int first )
{
	int i;
	t_hero const*   hero;
	std::string     spell_name = get_spell_name( m_current_spell );
	std::string     text;

	m_first_hero = first;
	text = get_mage_guild_text( m_current_spell );
	for (i = 0; i < k_hero_icon_count && i + m_first_hero < m_heroes.size(); i++)
	{
		hero = m_heroes[i + first];
		m_hero_frames[i].frame->set_visible( true );
		m_hero_frames[i].icon->set_visible( true );
		m_hero_frames[i].text->set_visible( true );
		m_hero_frames[i].icon->set_bitmap( hero->get_portrait() );
		m_hero_frames[i].text->set_text( replace_keywords( text, hero, m_current_spell, m_town->get_grail_data()));
	}
	while (i < k_hero_icon_count)
	{
		m_hero_frames[i].frame->set_visible( false );
		m_hero_frames[i].icon->set_visible( false );
		m_hero_frames[i].text->set_visible( false );
		i++;
	}
	m_last_hero_button->set_visible( first > 0 );
	m_next_hero_button->set_visible( first + k_hero_icon_count < m_heroes.size() );
	if (m_heroes.size() == 0)
	{
		m_hero_frames[0].text->set_text( replace_keywords( k_no_heroes_know, "%spell_name",
			                                               spell_name ) );
		m_hero_frames[0].text->set_visible( true );
	}
}

// -------------------------------------------------------------------
// window to display spells available in mage guild
// set hero display
// -------------------------------------------------------------------
void t_mage_guild_window::change_spell_set_visibility( bool visible )
{
	t_window_list::iterator iter;
	int highest_level = 0;
	int i;

	// Only display spell level labels and banners if they have the level of spells
	if( visible )
	{
		for (i = 0; i < m_spells.size(); i++)
		{
			int level;
			// spell icon
			level = get_spell_level( m_spells[i] );
			if( level > highest_level )
				highest_level = level;
		}
	}

	for (iter = m_icon_list[m_current_page].begin(); iter != m_icon_list[m_current_page].end(); ++iter)
		(*iter)->set_visible(visible);

	for (iter = m_spellname_list[m_current_page].begin(); iter != m_spellname_list[m_current_page].end(); ++iter)
		(*iter)->set_visible(visible);

	i = 0;
	for (iter = m_label_list[m_current_page].begin(); iter != m_label_list[m_current_page].end(); ++iter, ++i)
	{
		if( visible && i >= highest_level )
			continue;

		(*iter)->set_visible(visible);
	}

	i = 0;
	for (iter = m_level_banner_list[m_current_page].begin(); iter != m_level_banner_list[m_current_page].end(); ++iter, ++i)
	{
		if( visible && i >= highest_level )
			continue;

		(*iter)->set_visible(visible);
	}

	for (iter = m_label_banner_list[m_current_page].begin(); iter != m_label_banner_list[m_current_page].end(); ++iter)
		(*iter)->set_visible(visible);

	for (iter = m_frames_list[m_current_page].begin(); iter != m_frames_list[m_current_page].end(); ++iter)
		(*iter)->set_visible(visible);
}
